package bill.study.concurrency.synchronizer.exchanger.brian.goetz;

import java.util.ArrayList;
import java.util.Random;
import java.util.concurrent.Exchanger;

public class FillAndEmpty {
	Exchanger<DataBuffer> exchanger = new Exchanger<DataBuffer>();
	DataBuffer initialEmptyBuffer = new DataBuffer(new ArrayList<String>());
	DataBuffer initialFullBuffer = new DataBuffer(new ArrayList<String>());

	private  static int num = 0;

	class FillingLoop implements Runnable {

		@Override
		public void run() {
			DataBuffer currentBuffer = initialEmptyBuffer;
			try {
				while (currentBuffer != null) {
					addToBuffer(currentBuffer);
					Thread.sleep(new Random().nextInt(100));
					if (currentBuffer.full()) {
						currentBuffer = exchanger.exchange(currentBuffer);
					}
				}
			} catch (InterruptedException ie) {

			}

		}

		private void addToBuffer(DataBuffer currentBuffer) {
			String str = Thread.currentThread().getName();// + FillAndEmpty.num++;
			System.out.println("Adding " + str);
			currentBuffer.add(str);

		}

	}

	class EmptyingLoop implements Runnable {

		@Override
		public void run() {
			DataBuffer currentBuffer = initialFullBuffer;
			try {
				while (currentBuffer != null) {
					takeFromBuffer(currentBuffer);
					Thread.sleep(new Random().nextInt(100));
					if (currentBuffer.empty()) {
						currentBuffer = exchanger.exchange(currentBuffer);
					}
				}
			} catch (InterruptedException ie) {

			}

		}

		private void takeFromBuffer(DataBuffer currentBuffer) {
			String str =currentBuffer.remove();
			System.out.println("removing " + str  + "by "+ Thread.currentThread().getName());
		}

	}

	 void start() {
		new Thread(new FillingLoop()).start();
		new Thread(new EmptyingLoop()).start();
	}
	
	public static void main(String [] args){
		new FillAndEmpty().start();
	}
}
